package com.yun.util.yun.utils.date;

import com.alibaba.fastjson.JSONObject;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;


public class DateUtil {
    public static final int SECOND = 1000;

    public static final int MINUTE = SECOND * 60;

    public static final int HOUR = MINUTE * 60;

    public static final int DAY = HOUR * 24;

    public static final int WEEK = DAY * 7;

    public static final int YEAR = DAY * 365;

    private static final String DEF_OUT_FORMAT = "yyyy-MM-dd";

    /**
     *
     */
    public static long millionSecondsOfDay = 86400000;

    /**
     * @param date
     * @param i
     * @return
     */
    public static Date getDate(Date date, int i) {
        // long seconds = date.getTime() + i * 86400000;

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, i);

        return calendar.getTime();

    }

    /**
     * @param date
     * @param
     * @return
     */
    public static Date getDateByHour(Date date, int hour) {
        // long seconds = date.getTime() + i * 86400000;

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR, hour);

        return calendar.getTime();

    }

    public static Date getDateByMonth(Date date, int month) {
        // long seconds = date.getTime() + i * 86400000;

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, month);

        return calendar.getTime();

    }

    /**
     * @param date1
     * @param date2
     * @return
     */
    public static int getDay(Date date1, Date date2) {
        return (int) ((date2.getTime() - date1.getTime()) / millionSecondsOfDay);
    }

    public static int getMonth(Date start, Date end) {
        if (DateUtil.getYearOfDate(start) == DateUtil.getYearOfDate(end)) {
            return DateUtil.getMonthOfDate(end) - DateUtil.getMonthOfDate(start);
        } else if (DateUtil.getYearOfDate(start) <DateUtil.getYearOfDate(end)) {
            return (DateUtil.getYearOfDate(end) -DateUtil.getYearOfDate(start) - 1) * 12 + (12 - DateUtil.getMonthOfDate(start)) + (DateUtil.getMonthOfDate(end));
        } else {
            return -1;
        }
    }

    public static List<String> getMonthList(Date start, Date end) {
        int m = DateUtil.getMonth(start, end);
        List<String> list = new ArrayList();
        list.add(DateUtil.toStringByFormat(start, "yyyy-MM"));
        for (int i = 0; i < m - 1; i++) {
            Date nextDate =DateUtil.getDateByMonth(start, i + 1);
            list.add(DateUtil.toStringByFormat(nextDate, "yyyy-MM"));
        }
        list.add(DateUtil.toStringByFormat(end, "yyyy-MM"));
        return list;
    }

    /**
     * @param date Date
     * @return int
     */
    public static int getWeekOfDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return (calendar.get(Calendar.DAY_OF_WEEK) - 1) == 0 ? 7 : calendar.get(Calendar.DAY_OF_WEEK) - 1;
    }

    /**
     * @param year  int
     * @param month int
     * @param
     * @return int
     */
    public static int getDaysOfMonth(int year, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month - 1, 1);
        int monthDays = calendar.getActualMaximum(Calendar.DATE);
        return monthDays;
    }

    public static int getDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_MONTH);
    }

    public static int getMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MONTH) + 1;
    }

    public static int getYearOfDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.YEAR);
    }

    public static int getMonthOfDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MONTH) + 1;
    }

    public static java.sql.Date getSqlDate(Date date) {
        return new java.sql.Date(date.getTime());
    }

    /**
     * @param date Date
     * @return Date
     */
    public static Date getDate(Date date) {
        String str = dateToString(date);
        return getDate(str);

    }

    public static List<String> getDates(Date date1, Date date2) {
        int day = getDay(date1, date2);

        List<String> dates = new ArrayList<String>();

        for (int i = 0; i <= day; i++) {
            Date date = getDate(date1, i);
            dates.add(toStringByFormat(date, "yyyy-MM-dd"));
        }
        return dates;
    }

    public static List<String> getFormatDates(Date date1, Date date2, String format) {
        int day = getDay(date1, date2);

        List<String> dates = new ArrayList<String>();

        for (int i = 0; i <= day; i++) {
            Date date = getDate(date1, i);
            dates.add(toStringByFormat(date, format));
        }
        return dates;
    }

    /**
     * @param
     * @return String
     */
    public static String getUniueTimeString() {
        return String.valueOf(Calendar.getInstance().getTimeInMillis());
    }

    public static String dateToString(Date date) {
        if (date == null) {
            return "";
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String tmpStr = "";
        if (date != null) {
            tmpStr = sdf.format(date);
        }

        return tmpStr;
    }

    public static String datetimeToString(Date date) {
        if (date == null) {
            return "";
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        String tmpStr = "";
        if (date != null) {
            tmpStr = sdf.format(date);
        }

        return tmpStr;
    }

    public static String datetimesToString(Date date) {
        if (date == null) {
            return "";
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String tmpStr = "";
        if (date != null) {
            tmpStr = sdf.format(date);
        }

        return tmpStr;
    }

    public static String toStringByFormat(Date date, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        String tmpStr = "";
        if (date != null) {
            tmpStr = sdf.format(date);
        }

        return tmpStr;
    }

    public static Date toDateByFormat(String str, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        try {
            return sdf.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static Date stringToDate(String str) {
        // SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:MM:SS");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmm");
        try {
            return sdf.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static Date stringToDateTime(String str) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            if (null == str || str.isEmpty()) {
                return null;
            }
            return sdf.parse(str);
        } catch (ParseException e) {
            // e.printStackTrace();
            return null;
        }
    }

    public static Date stringToDatetime(String str) {
        if (str == null) {
            return null;
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        try {
            return sdf.parse(str);
        } catch (ParseException e) {
            // e.printStackTrace();
            return null;
        }
    }

    public static Date getDate(String str) {
        if (str == null || str.equals("")) {
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            return sdf.parse(str);
        } catch (ParseException e) {
            // e.printStackTrace();
            return null;
        }

    }

    public static String getTimeString(int duration) {
        int hours = duration / DateUtil.HOUR;
        int remain = duration - (hours * DateUtil.HOUR);
        int minutes = remain / DateUtil.MINUTE;
        StringBuffer time = new StringBuffer(64);
        if (hours != 0) {
            if (hours == 1) {
                time.append("1 hour and ");
            } else {
                time.append(hours).append(" hours and ");
            }
        }
        if (minutes == 1) {
            time.append("1 minute");
        } else {
            // what if minutes == 0 ???
            time.append(minutes).append(" minute(s)");
        }
        return time.toString();
    }

    /**
     * @param
     */
    public static boolean beforeEqual(Date f, Date t) {
        f = getDate(f);
        t = getDate(t);
        if (f.before(t) || f.equals(t)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * @param
     */
    public static boolean afterEqual(Date f, Date t) {
        f = getDate(f);
        t = getDate(t);
        if (f.after(t) || f.equals(t)) {
            return true;
        } else {
            return false;
        }

    }

    public static boolean between(Date d, Date s, Date e) {
        if (d.before(e) && d.after(s)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * @return yyyy-mm-dd
     */
    public static String getCurrentDateStr() {
        String curDateStr = "";

        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH) + 1;
        int day = cal.get(Calendar.DAY_OF_MONTH);

        curDateStr = String.valueOf(year) + "-";
        curDateStr += ((month < 10) ? "0" + String.valueOf(month) : String.valueOf(month)) + "-";
        curDateStr += ((day < 10) ? "0" + String.valueOf(day) : String.valueOf(day));

        return curDateStr;
    }


    /**
     * @return yyyy-mm
     */
    public static String getCurrentMonthStr() {
        String curDateStr = "";

        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH) + 1;
        //int day   = cal.get(Calendar.DAY_OF_MONTH);

        curDateStr = String.valueOf(year) + "-";
        curDateStr += ((month < 10) ? "0" + String.valueOf(month) : String.valueOf(month));

        return curDateStr;
    }

    public static String format(Date date, String outFormat) {
        return format(date, outFormat, Locale.ENGLISH);
    }

    public static String format(Date date, String outFormat, Locale locale) {
        if (outFormat == null || "".compareTo(outFormat) == 0) {
            outFormat = DEF_OUT_FORMAT;
        }
        SimpleDateFormat outDateFormat = null;
        if (locale == null) {
            outDateFormat = new SimpleDateFormat(outFormat, Locale.ENGLISH);
        } else {
            outDateFormat = new SimpleDateFormat(outFormat, locale);
        }
        String outDate = outDateFormat.format(date);
        return outDate;
    }

    public static Date getBeforetime(Date date, int interval) {
        GregorianCalendar gca = new GregorianCalendar();
        gca.setTime(date);
        gca.add(Calendar.MONTH, (-1) * interval);
        return gca.getTime();
    }

    //
    public static String getBeforetime(Date date) {
        return format(getBeforetime(date, 1), DEF_OUT_FORMAT);
    }

    //
    public static Date getFirstDateOfMonth(String dateString) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = sdf.parse(dateString);
        } catch (ParseException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        ca.set(Calendar.DAY_OF_MONTH, ca.getActualMinimum(Calendar.DAY_OF_MONTH));
        return ca.getTime();
    }


    public static Date getEndDateOfMonth(String dateString) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = sdf.parse(dateString);
        } catch (ParseException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
        return ca.getTime();
    }

    public static Date getFirstDateOfPreMonth(String dateString) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = sdf.parse(dateString);
        } catch (ParseException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
        Calendar ca = Calendar.getInstance();
        GregorianCalendar gca = new GregorianCalendar();
        gca.setTime(date);
        gca.add(Calendar.MONTH, (-1) * 1);
        ca.setTime(gca.getTime());
        ca.set(Calendar.DAY_OF_MONTH, ca.getActualMinimum(Calendar.DAY_OF_MONTH));
        return ca.getTime();
    }

    public static Date getEndDateOfPreMonth(String dateString) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = sdf.parse(dateString);
        } catch (ParseException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
        Calendar ca = Calendar.getInstance();
        GregorianCalendar gca = new GregorianCalendar();
        gca.setTime(date);
        gca.add(Calendar.MONTH, (-1) * 1);
        ca.setTime(gca.getTime());
        ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
        return ca.getTime();
    }

    /**
     * @param @param  date
     * @param @param  format
     * @param @return 设定文件
     * @return String 返回类型
     * @throws
     * @title: getDateStr
     * @description: TODO(获取指定格式的日期字符)
     * @author zhuyu 2016年11月9日 上午10:13:24
     */
    public static String getDateStr(Date date, String format) {
        SimpleDateFormat dateSdf = new SimpleDateFormat(format);
        String dateStr = dateSdf.format(date);
        return dateStr;
    }

    public static JSONObject getTitleStr(Integer type, Date startDate, Date endDate) {
        JSONObject jo = new JSONObject();
        String stTypeCn = "";
        String subTitle = "";
        if (type == 1) {
            stTypeCn = "本周工单数";
            subTitle = DateUtil.getDateStr(startDate, "yyyy年mm月dd日 至今");
        } else if (type == 2) {
            stTypeCn = "本月工单数";
            subTitle = DateUtil.getDateStr(startDate, "yyyy年mm月dd日 至今");
        } else if (type == 3) {
            stTypeCn = "本季度工单数";
            subTitle =DateUtil.getDateStr(startDate, "yyyy年mm月dd日 至今");
        } else if (type == 4) {
            stTypeCn = "本年工单数";
            subTitle =DateUtil.getDateStr(startDate, "yyyy年mm月dd日 至今");
        } else {
            stTypeCn = "工单数";
            subTitle =DateUtil.getDateStr(startDate, "yyyy年mm月dd日 至 ") + DateUtil.getDateStr(endDate, "yyyy年mm月dd日");
        }
        return jo;
    }

    public static JSONObject getTitleOrgStr(String organizationId, String organizationName, Date startDate, Date endDate) {
        JSONObject jo = new JSONObject();
        String stTypeCn = "";
        String subTitle = "";
        if (organizationId != null) {
            stTypeCn = organizationName+"工单数";
        } else {
            stTypeCn = "工单数";
        }
        subTitle = DateUtil.getDateStr(startDate, "yyyy年mm月dd日 至 ") + DateUtil.getDateStr(endDate, "yyyy年mm月dd日");

        return jo;
    }

    /**
     * @param @return 设定文件
     * @return Date 返回类型
     * @throws
     * @title: getWeekStartDate
     * @description: TODO(获取本周第一天的日期)
     * @author zhuyu 2016年11月9日 上午10:01:21
     */
    public static Date getWeekStartDate() {
        Calendar cal = Calendar.getInstance();
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        Date date = cal.getTime();
        return date;
    }

    /**
     * @param @return 设定文件
     * @return Date 返回类型
     * @throws
     * @title: getMonthStartDate
     * @description: TODO(获取本月第一天的日期)
     * @author zhuyu 2016年11月9日 上午10:03:42
     */
    public static Date getMonthStartDate() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.MONTH, 0);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        Date date = cal.getTime();
        return date;
    }

    /**
     * @param @return 设定文件
     * @return Date 返回类型
     * @throws
     * @title: getCurrentQuarterStartTime
     * @description: TODO(获取本季度第一天的日期)
     * @author zhuyu 2016年11月9日 上午10:07:28
     */
    public static Date getQuarterStartDate() {
        Calendar cal = Calendar.getInstance();
        int currentMonth = cal.get(Calendar.MONTH) + 1;
        if (currentMonth >= 1 && currentMonth <= 3) {
            cal.set(Calendar.MONTH, 0);
        } else if (currentMonth >= 4 && currentMonth <= 6) {
            cal.set(Calendar.MONTH, 3);
        } else if (currentMonth >= 7 && currentMonth <= 9) {
            cal.set(Calendar.MONTH, 4);
        } else if (currentMonth >= 10 && currentMonth <= 12) {
            cal.set(Calendar.MONTH, 9);
        }
        cal.set(Calendar.DATE, 1);
        Date date = cal.getTime();
        return date;
    }

    /**
     * @param @return 设定文件
     * @return Date 返回类型
     * @throws
     * @title: getYearStartDate
     * @description: TODO(获取本年的第一天日期)
     * @author zhuyu 2016年11月9日 上午10:09:26
     */
    public static Date getYearStartDate() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.MONTH, 0);
        cal.set(Calendar.DATE, 1);
        Date date = cal.getTime();
        return date;
    }

    /**
     * <p>Method: getDateStr </p>
     * <p>Description:获取指定格式的日期字符 </p>
     * <p>date: 2018/11/8 9:10 </p>
     *
     * @author zhuyu[zhuyu@boco.com.cn]
     */
    public static String getDate2Str(Date date, String format) {
        SimpleDateFormat dateSdf = new SimpleDateFormat(format);
        String dateStr = dateSdf.format(date);
        return dateStr;
    }

    /**
     * @param @return 设定文件
     * @return Date 返回类型
     * @throws
     * @title: getDataWeekBefor
     * @description: TODO(获取一周前日期)
     * @author zhuyu 2016年11月13日 下午5:55:56
     */
    public static Date getDateWeekBefor() {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DATE, -6);
        Date date = c.getTime();
        return date;
    }


    /**
     * @param @return 设定文件
     * @return Date 返回类型
     * @throws
     * @title: getDataWeekBefor
     * @description: TODO(获取30天前日期)
     * @author zhuyu 2016年11月13日 下午5:55:56
     */
    public static Date getDateMonthBefor() {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DATE, -29);
        Date date = c.getTime();
        return date;
    }

    /**
     * @param @return 设定文件
     * @return Date 返回类型
     * @throws
     * @title: getDateYearBefor
     * @description: TODO(获取一年前日期)
     * @author zhuyu 2016年11月13日 下午6:00:27
     */
    public static Date getDateYearBefor() {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.YEAR, -1);
        c.add(Calendar.MONTH, +1);
        Date date = c.getTime();
        return date;
    }

    public static void main(String[] args) {
        String startStr = "2009/05";
        String endStr = "2010/03";
        List<String> list = DateUtil.getMonthList(DateUtil.toDateByFormat(startStr, "yyyy/MM"), DateUtil.toDateByFormat(endStr, "yyyy/MM"));
        System.out.println(list.size());
    }
}

